/**
 *  学习目标：Todos 案例
 *  需求1：✅组件拆分
 *  需求2：✅声明数据、渲染任务列表
 *  需求3：✅根据id，更新任务的状态
 *  需求4：✅根据id，删除一条任务
 *  需求5：✅新增一条数据
 *  需求6：✅数据缓存
 *  需求7：✅小选影响全选
 *  需求8：✅全选影响小选
 *  需求9：✅数据切换-点谁谁有边框
 *  需求10：✅数据切换
 */
import React, { useEffect, useState } from 'react';
import Footer from './components/Footer';
import Header from './components/Header';
import Main from './components/Main';
import './styles/base.css';
import './styles/index.css';

export default function App() {
  // 2.1. App组件中声明list 和 type ,需要状态提升，兄弟组件通信

  // 6.3 从缓存中取出初始值
  const [list, setList] = useState(JSON.parse(localStorage.getItem('todo-list') || '[]'));
  const [type, setType] = useState('all');

  // 3.1 App中定义更新状态的函数
  const handleUpdateById = (id) => {
    // 3.4 完成更新的逻辑
    const newList = [...list];
    const index = newList.findIndex((item) => item.id === id);
    newList[index].isDone = !newList[index].isDone;
    setList(newList);
  };

  // 4.1 定义删除的函数
  const handleDelById = (id) => {
    // 4.4. 完成计算
    const newList = list.filter((item) => item.id !== id);
    setList(newList);
  };
  // 5.3 在APp组件中定义新增的函数
  const handleAdd = (task) => {
    // 5.6 完成新增的计算
    const newTask = { task, isDone: false, id: Date.now() };
    setList([newTask, ...list]);
  };
  // 8.1 定义一个全选的函数
  const handleCheckAll = (e) => {
    console.log('e  ----->  ', e.target.checked);
    const newList = list.map((item) => {
      return { ...item, isDone: e.target.checked };
    });
    setList(newList);
  };

  // 6.1. 使用useEffect监听list的变化
  useEffect(() => {
    // 6.2. 更新后的值，存缓存
    localStorage.setItem('todo-list', JSON.stringify(list));
  }, [list]);

  // 💥 模拟计算属性原理：setState会导致组件重新渲染，声明的变量会被重新计算
  // 7.1 在return之前，声明计算属性isAll
  const isAll = list.length ? list.every((item) => item.isDone) : false;

  // 10.1 定义计算属性showList
  const showList = list.filter((item) => {
    // 如果type为active 返回item.isDone为false的，表示要未完成的
    if (type === 'active') return !item.isDone;
    // 如果type为completed 返回item.isDone为true的，表示要完成的
    if (type === 'completed') return item.isDone;
    // 如果type为all 返回true，表示要全不的数据
    return true;
  });

  return (
    <section className="todoapp">
      {/* 头部 */}
      <Header
        // 5.4 子传父：回调函数
        handleAdd={handleAdd}
      />
      {/* 主体 */}
      <Main
        // 2.2. 父传子给Main传来list
        // 10.2 数据切换
        list={showList}
        // 3.2 父传子回调函数
        handleUpdateById={handleUpdateById}
        // 4.2 子传父给Main传函数
        handleDelById={handleDelById}
        // 7.2 父传子给Main组件传isAll
        isAll={isAll}
        // 8.2
        handleCheckAll={handleCheckAll}
      />
      {/* 底部 */}
      <Footer
        // 9.1 父传子type
        type={type}
        // 9.3 父组件传函数
        handleType={setType}
      />
    </section>
  );
}
